#ifndef LOG_H
#define LOG_H

#include <core/string.h>
#include <core/core.h>
namespace Core
{
    //interface for formatting log message
    class LogOutput
    {
    public:
        LogOutput(){}
        enum MessageType
        {
            Warning,
            Info,
            Notice,
            Error
        };
        static String MessageTypeToString(MessageType type);

        virtual void print(MessageType typeOfMessage, const std::string& filename, int line, const Core::String& s) = 0;
        virtual void print(MessageType typeOfMessage, const Core::String& s) = 0;
    };

    //log
    class Log
    {
        typedef int LogOutputHash;
        typedef std::map<LogOutputHash, LogOutput*> OUTPUTS_MAP;
        OUTPUTS_MAP m_outputs;
        static LogOutputHash hash(const LogOutput*);
    public:
        static Log& instance();

        void addLogFormat(const LogOutput*);
        void removeLogFormat(const LogOutput*);

        //print message for all formats attached
        void print(LogOutput::MessageType msgType, const std::string& filename,
                   int line, const Core::String& s);

        void print(LogOutput::MessageType msgType, const Core::String& s);

        Log();
        ~Log();
    };

    class TextLogOutput : public LogOutput
    {
        std::ostream* m_outputStream;
    public:
        TextLogOutput(std::ostream& o);
        ~TextLogOutput();
        std::ostream& stream() const {return *m_outputStream;}
        virtual void  print(MessageType typeOfMessage, const std::string& filename, int line, const Core::String& s);
        virtual void  print(MessageType typeOfMessage, const Core::String& s);
    };
    class Interface
    {
    public:
        virtual void test1() = 0;
    };
    class CORE_API Interface2
    {
    public:
        std::string get();
    private:
    };
    CORE_API std::string GetSomeInterface();
}

#endif